define(function (require, exports, module) {
    const {events, geojsonTypes, updateActions} = require('./utils/constants.js').onload();
    const difference = turf.difference

    function onload() {
        const CutPolygon = {}
        const CutPolygonEvents = Object.assign({
            UPDATE_CUT: 'draw.update.cut'
        }, events)

        CutPolygon.onSetup = function () {
            let main = this.getSelected()
                .filter((f) => f.type === "Polygon" || f.type === "MultiPolygon")
                .map((f) => f.toGeoJSON());

            if (main.length < 1) {
                throw new Error(
                    "Please select a feature/features (Polygon or MultiPolygon) to split!"
                );
            }

            return {
                main,
            };
        };

        CutPolygon.toDisplayFeatures = function (state, geojson, display) {
            display(geojson);

            this.changeMode("passing_mode_polygon", (cuttingpolygon) => {
                state.main.forEach((feature, idx) => {
                    if (
                        feature.geometry.type === geojsonTypes.POLYGON ||
                        feature.geometry.type === geojsonTypes.MULTI_POLYGON
                    ) {
                        if (feature.geometry.type === geojsonTypes.POLYGON) {
                            const allCoords = []
                            const coordinates = feature.geometry.coordinates[0]
                            for (let i = 0; i < coordinates.length; i++) {
                                const coordinate = feature.geometry.coordinates[0][i]
                                if (("" + coordinate[0]).length > 6 && ("" + coordinate[1]).length > 6) {
                                    allCoords.push(coordinate)
                                }
                            }
                            feature.geometry.coordinates[0] = allCoords
                        } else if (feature.geometry.type === geojsonTypes.MULTI_POLYGON) {
                            const allCoords = []
                            const coordinates = feature.geometry.coordinates[0][0]
                            for (let i = 0; i < coordinates.length; i++) {
                                const coordinate = feature.geometry.coordinates[0][0][i]
                                if (("" + coordinate[0]).length > 6 && ("" + coordinate[1]).length > 6) {
                                    allCoords.push(coordinate)
                                }
                            }
                            feature.geometry.coordinates[0][0] = allCoords
                        }
                        let afterCut = difference(feature, cuttingpolygon);
                        if (feature.geometry.type === geojsonTypes.MULTI_POLYGON && feature.geometry.coordinates.length > 1) {
                            // 解决剪切时各个子面乱序问题（这里只需要保证第一个面，一直在第一个位置即可）
                            // 第一个面的外环json
                            let firstJSON =  JSON.stringify(feature.geometry.coordinates[0][0])
                            // 切割后第一个面被分配到哪个下标
                            let firstIndex
                            let firstPolygon
                            const afterCoordinates = afterCut.geometry.coordinates;
                            for (let i = 0; i < afterCoordinates.length; i++) {
                                const polygon = afterCoordinates[i];
                                if (firstJSON === JSON.stringify(polygon[0])) {
                                    firstIndex = i
                                    firstPolygon = polygon
                                    break
                                }
                            }
                            // 最终的坐标
                            const finalAfterCoordinates = firstPolygon ? [firstPolygon] : []
                            for (let i = 0; i < afterCoordinates.length; i++) {
                                if (firstIndex !== i) {
                                    finalAfterCoordinates.push(afterCoordinates[i])
                                }
                            }
                            afterCut.geometry.coordinates = finalAfterCoordinates
                        }
                        let newF = this.newFeature(afterCut);
                        newF.id = feature.id;
                        this.addFeature(newF);
                        this.fireUpdate(newF);
                    } else {
                        console.info("The feature is not Polygon/MultiPolygon!");
                    }
                });
            });
        };

        CutPolygon.fireUpdate = function(newF) {
            this.map.fire(CutPolygonEvents.UPDATE_CUT, {
                action: updateActions.CHANGE_COORDINATES,
                features: newF.toGeoJSON()
            });
        };

        return {
            CutPolygon,
            CutPolygonEvents
        }
    }

    module.exports = {
        onload
    }
});
